<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //存储代理对象和依赖 key为目标对象,value为目标对象key作为key 依赖函数构成数组为value的map对象
      let targetMap = new WeakMap();
      let num1 = 0;
      let product = { num2: 30, num3: 40 };
      //依赖关系函数
      let effect = () => {
        num1 = proxyObj.num2 * proxyObj.num3;
      };
      //依赖收集函数
      const gather = (target, key) => {
        //获取依赖
        let depsMap = targetMap.get(target);

        if (!depsMap) {
          targetMap.set(target, (depsMap = new Map()));
        }
        //获取依赖的函数
        let dep = depsMap.get(key);
        if (!dep) {
          depsMap.set(key, (dep = new Set()));
        }
        dep.add(effect);
      };

      //执行函数
      const trigger = (target, key) => {
        //获取依赖
        let depsMap = targetMap.get(target);
        if (!depsMap) return;
        let dep = depsMap.get(key);
        //执行所有依赖函数
        dep.forEach((effect) => {
          effect();
        });
      };

      //代理函数
      function reactive(target) {
        //代理回调
        const handel = {
          get(target, key, receiver) {
            console.log("正在读取" + key);
            //调用收集依赖函数
            gather(target, key);
            return Reflect.get(target, key, receiver);
          },
          set(target, key, newValue, receiver) {
            console.log("正在修改" + key);

            const oldValue = target[key];
            const result = Reflect.set(target, key, newValue, receiver);

            if (oldValue != result) {
              //调用执行函数
              trigger(target, key);
            }

            return result;
          },
        };

        return new Proxy(target, handel);
      }

      // function reactive(target) {
      //   const handler = {
      //     // ① 封装统一处理函数对象
      //     get(target, key, receiver) {
      //       console.log("正在读取的数据：", key);
      //       return Reflect.get(target, key, receiver);
      //     },
      //     set(target, key, value, receiver) {
      //       console.log("正在修改的数据：", key, ",值为：", value);
      //       return Reflect.set(target, key, value, receiver);
      //     },
      //   };

      //   return new Proxy(target, handler); // ② 统一调用 Proxy API
      // }

      // let product = reactive({ price: 10, quantity: 2 }); // ③ 将对象转换为响应式对象
      // product.price = 20;
      // console.log(product.price);

      let proxyObj = reactive(product);
      effect();
      console.log(num1);
      proxyObj.num2 = 20;

      console.log(num1);
    </script>
  </body>
</html>
